/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.dtgenerator;

import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bef.dtgenerator.common.IMetadataPool;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.variable.CommonVariableEntity;
import com.inspur.edp.cef.generator.overall.commonModel.CommonModelGeneratorContext;
import com.inspur.edp.cef.variable.dtgenerator.VariableGeneratorContext;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import org.springframework.beans.factory.annotation.Autowired;

public class BEGeneratorContext extends CommonModelGeneratorContext implements IMetadataPool {
  // public Dictionary<string, Type>getParentEntityTypes() { return ParentBEGenContext.EntityTypes;
  // }

  // region MetadataCache
  private final Object mdPoolLock = new Object();
  // key是元数据id, 如果要求包名改成包名+id
  private final java.util.HashMap<MetaKey, GspMetadata> metadataPools =
      new java.util.HashMap<MetaKey, GspMetadata>();
  private GspBusinessEntity privateParentBE;
  private GspBusinessEntity privateBE;

  // public override string ParentNamespace {getget() { return ParentBE.GeneratingAssembly; } }
  // 生成部署工具配置文件时使用，后续可以删掉
  private String privateServerPath;
  private String genPath = "";
  private String privateRelativeGeneratePath;
  // internal GeneratorCommonContext ParentBEGenContext { get; set; }
  private boolean privateIsParentBEInSameProj;

  // public bool PreGenerating { get; set; }
  //	private Assembly privateParentBEAssembly;
  private String privateCoreAssemblyName;
  //	@Autowired
  //	private RuntimeService lcmRtService;
  @Autowired
  private RefCommonService lcmDtService;

  //// public Dictionary<string, MediateType> EntityAssemblerFactoryInterfaceTypes { get; }

  private VariableGeneratorContext privateVarGenCtx;

  //	private java.util.HashMap<String, Assembly> copiedAssembly = new java.util.HashMap<String,
  // Assembly>();
  public BEGeneratorContext() {
    // todo:wj
    // EntityAssemblerFactoryInterfaceTypes = new Dictionary<string, MediateType>();
  }

  @Override
  public String getDataTypeNamespace() {
    return getBE().getGeneratingAssembly() + "." + getBE().getCode().toLowerCase();
  }

  @Override
  public IGspCommonDataType getCommonDataType() {
    return getBE().getMainObject();
  }
  //	private String getBinPath() { return Path.Combine(PathTransform.GetUserProjectsRoot(),
  // ServiceManager.<IMetadataService>GetService().GetRefPath(MetadataPath)); }

  // internal bool IsParentBeInCurrentProject { get; set; }

  public final GspBusinessEntity getParentBE() {
    return privateParentBE;
  }

  public final void setParentBE(GspBusinessEntity value) {
    privateParentBE = value;
  }

  public final GspBusinessEntity getBE() {
    return privateBE;
  }

  public boolean hasVariables() {
    CommonVariableEntity varEntity = getBE().getVariables();
    return (varEntity != null && !varEntity.getContainElements().isEmpty()) || (
        varEntity.getDtmAfterModify() != null && !varEntity.getDtmAfterModify().isEmpty());
  }

  private VariableGeneratorContext varGenerateContext;

  public VariableGeneratorContext getVarGenerateContext() {
    return varGenerateContext;
  }

  public void setVarGenerateContext(VariableGeneratorContext varGenerateContext) {
    this.varGenerateContext = varGenerateContext;
  }

  public final void setBE(GspBusinessEntity value) {
    privateBE = value;
  }

  public final String getServerPath() {
    return privateServerPath;
  }

  public final void setServerPath(String value) {
    privateServerPath = value;
  }

  // public override  String getParentGeneratePath() { return ParentBEGenContext?.GeneratedPath; }

  // public override  String getParentRelativeGeneratePath() { return
  // ParentBEGenContext?.RelativeGeneratedPath; }

  // public override Dictionary<string, Type>getParentEntityAllInterfaceTypes() { return throw new
  // NotImplementedException(); }

  public final void setGenPath(String path) {
    this.genPath = path;
  }

  @Override
  public String getGeneratePath() {
    return genPath;
  }

  public final String getRelativeGeneratePath() {
    return privateRelativeGeneratePath;
  }

  public final void setRelativeGeneratePath(String value) {
    privateRelativeGeneratePath = value;
  }

  // internal BefEntityGenerator EntityGenerator { get; set; }

  public final boolean getIsParentBEInSameProj() {
    return privateIsParentBEInSameProj;
  }

  public final void setIsParentBEInSameProj(boolean value) {
    privateIsParentBEInSameProj = value;
  }

  //	public final Assembly  getParentBEAssembly()
  //	{
  //		return privateParentBEAssembly;
  //	}

  //	public final void  setParentBEAssembly(Assembly value)
  //	{
  //		privateParentBEAssembly = value;
  //	}

  public IMetadataPool getMetadataPool() {
    return this;
  }

  public final String getCoreAssemblyName() {
    return privateCoreAssemblyName;
  }

  public final void setCoreAssemblyName(String value) {
    privateCoreAssemblyName = value;
  }

  public RefCommonService getLcmDtService() {
    return lcmDtService;
  }
  //
  //	@Override
  //	public <T extends IMetadataContent> T getMetadataContent(String packageName, String id)
  //	{
  //		if (DotNetToJavaStringHelper.isNullOrEmpty(packageName))
  //		{
  //			packageName = null;
  //		}
  //		MetaKey key = new MetaKey(id, packageName);
  //		synchronized (mdPoolLock)
  //		{
  //			GspMetadata metadata = metadataPools.get(key);
  //			if (metadata != null)
  //			{
  //				metadata = getLcmDtService().getRefMetadata(id);
  //				metadataPools.put(key.clone(), metadata);
  //			}
  //			return (T)metadata.getContent();
  //		}
  //	}

  //	public GspMetadata  getMetadata(String packageName, String id)
  //	{
  //		if (DotNetToJavaStringHelper.isNullOrEmpty(packageName))
  //		{
  //			packageName = null;
  //		}
  //		MetaKey key = new MetaKey(id, packageName);
  //		synchronized (mdPoolLock)
  //		{
  //			if (!((GspMetadata metadata = metadataPools.get(key.clone())) != null))
  //			{
  //				metadata = getLcmDtService().GetRefMetadata(id);
  //				metadataPools.put(key.clone(), metadata);
  //			}
  //			return metadata;
  //		}
  //	}

  // endregion

  //	private String  getMetadataNamespace(String path)
  //	{
  //		return
  // ServiceManager.<IMetadataService>GetService().getMetadataWithoutContent(path).Header.NameSpace;
  //	}
  //
  //	private String  getMetadataNamespace(String packageName, String id)
  //	{
  //		if (DotNetToJavaStringHelper.isNullOrEmpty(packageName))
  //		{
  //			packageName = null;
  //		}
  //		MetaKey key = new MetaKey(id, packageName);
  //		synchronized (mdPoolLock)
  //		{
  //			if (!((GspMetadata metadata = metadataPools.get(key.clone())) != null))
  //			{
  //				//metadata = lcmRtService.getMetadata(new MetadataFilter
  //				//{
  //				//    PackageName = packageName,
  //				//    MetadataID = id
  //				//});
  //				metadata = getLcmDtService().GetRefMetadata(id);
  //				metadataPools.put(key.clone(), metadata);
  //			}
  //			return metadata.Header.NameSpace;
  //		}
  //
  //
  //	}

  public final VariableGeneratorContext getVarGenCtx() {
    return privateVarGenCtx;
  }

  public final void setVarGenCtx(VariableGeneratorContext value) {
    privateVarGenCtx = value;
  }
  //
  //	public final java.lang.Class  getCustomActionType(String mdId, String assemblyName, String
  // className)
  //	{
  //		DataValidator.checkForEmptyString(assemblyName, "assemblyName");
  //		DataValidator.checkForEmptyString(className, "className");
  //
  //		if (!((var assembly = copiedAssembly.get(assemblyName)) != null))
  //		{
  //			assembly = Inspur.Gsp.Lcm.MetadataJit.Api.Utils.GetAssembly(assemblyName, BinPath,
  // Lcm.MetadataJit.Api.Utils.OutPutPath);
  //			//assembly = MdReflectionUtil.GetAssembly(mdId, assemblyName,
  ////                Path.Combine(PathTransform.GetUserProjectsRoot(),
  // ServiceManager.GetService<IMetadataService>().GetRefPath(MetadataPath)),
  ////                GeneratePath);
  //			copiedAssembly.put(assemblyName, assembly);
  //		}
  //		return getTypeFromAssembly(assembly, className);
  //	}
  //
  //	private java.lang.Class  getTypeFromAssembly(Assembly assembly, String className)
  //	{
//		var type = assembly.GetType(className);
  //		if (type == null)
  //		{
  //			throw new GSPException("BeGen_1003", Utils.FormatExceptionMsg("程序集%1$s中不存在类型{1}，请尝试重新编译构件。",
  // assembly.FullName, className));
  //		}
  //		return type;
  //	}

//  public TypeInfo getMgrAssFactoryInterfaceType() {
//    MediateType mt = ApiHelper.getMgrAssFactoryInterfaceClassName(getBE());
//    TypeInfo result = new TypeInfo(mt.getClassName());
//    result.setTypePackageName(mt.getNamespace());
//    return result;
//  }

// this class will differ from the original:
  // ORIGINAL LINE: private struct MetaKey
  private static final class MetaKey {

    private String privateId;
    private String privatePackageName;

    public MetaKey(String id, String packageName) {
      this.setId(id);
      this.setPackageName(packageName);
    }

    public String getId() {
      return privateId;
    }

    public void setId(String value) {
      privateId = value;
    }

    public String getPackageName() {
      return privatePackageName;
    }

    public void setPackageName(String value) {
      privatePackageName = value;
    }

    @Override
    public MetaKey clone() {
      return new MetaKey(privateId, privatePackageName);
    }
  }
}
